package cn.cleanarch.infra.idp.s3.service.impl;

import cn.cleanarch.infra.idp.commons.domain.dto.PageResult;
import cn.cleanarch.infra.idp.commons.utils.Times;
import cn.cleanarch.infra.idp.database.utils.Pages;
import cn.cleanarch.infra.idp.s3.dao.repository.S3ConfigRepository;
import cn.cleanarch.infra.idp.s3.domain.dto.S3CacheStatus;
import cn.cleanarch.infra.idp.s3.domain.dto.S3ConfigDTO;
import cn.cleanarch.infra.idp.s3.domain.dto.S3ConfigStatus;
import cn.cleanarch.infra.idp.s3.domain.entity.S3Config;
import cn.cleanarch.infra.idp.s3.domain.query.S3ConfigQuery;
import cn.cleanarch.infra.idp.s3.service.S3ConfigCacheService;
import cn.cleanarch.infra.idp.s3.service.S3ConfigService;
import cn.cleanarch.infra.idp.s3.service.S3Service;
import cn.cleanarch.infra.idp.uaa.core.util.LoginSessionTool;
import cn.cleanarch.infra.idp.web.exception.Exceptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * S3配置服务实现类
 */
@Service
public class S3ConfigServiceImpl implements S3ConfigService {

    private static final Logger logger = LoggerFactory.getLogger(S3ConfigServiceImpl.class);

    private final S3ConfigRepository s3ConfigRepository;
    private final S3Service s3Service;
    private final S3ConfigCacheService s3ConfigCacheService;

    public S3ConfigServiceImpl(S3ConfigRepository s3ConfigRepository, S3Service s3Service, S3ConfigCacheService s3ConfigCacheService) {
        this.s3ConfigRepository = s3ConfigRepository;
        this.s3Service = s3Service;
        this.s3ConfigCacheService = s3ConfigCacheService;
    }

    @Override
    public PageResult<S3ConfigDTO> pageQuery(S3ConfigQuery query) {
        QueryWrapper<S3Config> wrapper = new QueryWrapper<>();
        
        // 根据名称模糊查询
        if (query.getName() != null && !query.getName().isEmpty()) {
            wrapper.like("name", query.getName());
        }
        
        // 根据业务类型模糊查询
        if (query.getBusinessType() != null && !query.getBusinessType().isEmpty()) {
            wrapper.like("business_type", query.getBusinessType());
        }
        
        // 根据启用状态查询
        if (query.getEnabled() != null) {
            wrapper.eq("enabled", query.getEnabled());
        }
        
        // 按创建时间倒序排列
        wrapper.orderByDesc("create_time");

        Page<S3Config> page = s3ConfigRepository.page(Pages.of(query), wrapper);
        PageResult<S3Config> entityPageResult = Pages.result(page);
        
        // 手动转换S3Config实体到S3ConfigDTO
        List<S3ConfigDTO> dtoList = entityPageResult.getPageData().stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
        
        return new PageResult<>(entityPageResult.getTotal(), dtoList);
    }

    @Override
    public S3Config getById(Long id) {
        return s3ConfigCacheService.getCachedById(id);
    }

    @Override
    @Transactional
    public S3ConfigDTO create(S3ConfigDTO dto) {
        // 检查业务类型是否已存在
        QueryWrapper<S3Config> wrapper = new QueryWrapper<>();
        wrapper.eq("business_type", dto.getBusinessType());
        if (s3ConfigRepository.exists(wrapper)) {
            Exceptions.throwException("该业务类型已存在配置");
        }

        S3Config config = new S3Config();
        config.setName(dto.getName());
        config.setBusinessType(dto.getBusinessType());
        config.setEndpoint(dto.getEndpoint());
        config.setAccessKey(dto.getAccessKey());
        config.setSecretKey(dto.getSecretKey());
        config.setBasePath(dto.getBasePath()); // 添加basePath字段
        config.setBucket(dto.getBucket());
        config.setRegion(dto.getRegion());
        config.setDescription(dto.getDescription());
        config.setEnabled(dto.getEnabled());
        config.setPathStyle(dto.getPathStyle()); // 添加pathStyle字段
        
        // 设置审计字段
        LocalDateTime now = LocalDateTime.now();
        config.setCreateTime(now);
        config.setUpdateTime(now);
        config.setCreateBy(LoginSessionTool.getCurrentUser().getUserId());
        config.setUpdateBy(LoginSessionTool.getCurrentUser().getUserId());

        s3ConfigRepository.save(config);
        
        // 清除缓存
        s3ConfigCacheService.evictAllConfigCache();
        
        return convertToDTO(config);
    }

    @Override
    @Transactional
    public S3ConfigDTO update(S3ConfigDTO dto) {
        S3Config existing = s3ConfigRepository.getById(dto.getId());
        if (existing == null) {
            Exceptions.throwException("S3配置不存在");
        }

        // 检查业务类型是否被其他配置使用（除了当前配置）
        QueryWrapper<S3Config> wrapper = new QueryWrapper<>();
        wrapper.eq("business_type", dto.getBusinessType());
        wrapper.ne("id", dto.getId()); // 排除当前配置
        if (s3ConfigRepository.exists(wrapper)) {
            Exceptions.throwException("该业务类型已存在配置");
        }

        existing.setName(dto.getName());
        existing.setBusinessType(dto.getBusinessType());
        existing.setEndpoint(dto.getEndpoint());
        existing.setAccessKey(dto.getAccessKey());
        existing.setSecretKey(dto.getSecretKey());
        existing.setBasePath(dto.getBasePath()); // 更新basePath字段
        existing.setBucket(dto.getBucket());
        existing.setRegion(dto.getRegion());
        existing.setDescription(dto.getDescription());
        existing.setEnabled(dto.getEnabled());
        existing.setPathStyle(dto.getPathStyle()); // 更新pathStyle字段
        
        existing.setUpdateTime(LocalDateTime.now());
        existing.setUpdateBy(LoginSessionTool.getCurrentUser().getUserId());
        
        s3ConfigRepository.updateById(existing);
        
        // 清除缓存
        s3ConfigCacheService.evictAllConfigCache();
        
        return convertToDTO(existing);
    }

    @Override
    @Transactional
    public Boolean delete(Long id) {
        if (id == null) {
            return false;
        }
        
        S3Config config = s3ConfigRepository.getById(id);
        if (config == null) {
            return false;
        }
        
        s3ConfigRepository.removeById(id);
        
        // 清除缓存
        s3ConfigCacheService.evictAllConfigCache();
        
        return true;
    }

    @Override
    public List<S3Config> getAllEnabledConfigs() {
        logger.info("开始获取所有启用的S3配置");
        List<S3Config> configs = s3ConfigCacheService.getCachedAllEnabledConfigs();
        logger.info("获取到启用的S3配置数量: {}", configs.size());
        for (S3Config config : configs) {
            logger.debug("启用的S3配置 - ID: {}, 业务类型: {}, 端点: {}", 
                        config.getId(), config.getBusinessType(), config.getEndpoint());
        }
        return configs;
    }

    @Override
    public S3Config getByBusinessType(String businessType) {
        logger.info("开始获取业务类型对应的S3配置 - 业务类型: {}", businessType);
        S3Config config = s3ConfigCacheService.getCachedByBusinessType(businessType);
        if (config != null) {
            logger.info("成功获取业务类型对应的S3配置 - 业务类型: {}, 配置ID: {}, 端点: {}", 
                       businessType, config.getId(), config.getEndpoint());
        } else {
            logger.warn("未找到业务类型对应的S3配置 - 业务类型: {}", businessType);
        }
        return config;
    }

    /**
     * 将S3Config实体转换为S3ConfigDTO
     */
    private S3ConfigDTO convertToDTO(S3Config config) {
        S3ConfigDTO dto = new S3ConfigDTO();
        dto.setId(config.getId());
        dto.setName(config.getName());
        dto.setBusinessType(config.getBusinessType());
        dto.setEndpoint(config.getEndpoint());
        dto.setAccessKey(config.getAccessKey());
        dto.setBasePath(config.getBasePath());
        dto.setBucket(config.getBucket());
        dto.setRegion(config.getRegion());
        dto.setDescription(config.getDescription());
        dto.setEnabled(config.getEnabled());
        dto.setPathStyle(config.getPathStyle());
        dto.setCreateBy(config.getCreateBy());
        dto.setUpdateBy(config.getUpdateBy());
        return dto;
    }

    @Override
    public boolean testConnection(Long id) {
        S3Config config = s3ConfigCacheService.getCachedById(id);
        if (config == null) {
            return false;
        }

        return s3Service.testConnection(config);
    }

    @Override
    public S3ConfigStatus getStatus() {
        S3ConfigStatus status = new S3ConfigStatus();
        
        // 获取总配置数
        long total = s3ConfigRepository.count();
        status.setTotalConfigs((int)total);
        
        // 获取已启用配置数
        QueryWrapper<S3Config> enabledWrapper = new QueryWrapper<>();
        enabledWrapper.eq("enabled", true);
        long enabled = s3ConfigRepository.count(enabledWrapper);
        status.setEnabledConfigs((int)enabled);
        
        // 计算已禁用配置数
        status.setDisabledConfigs((int)(total - enabled));
        
        return status;
    }

    @Override
    public S3CacheStatus getCacheStatus() {
        S3CacheStatus cacheStatus = new S3CacheStatus();
        
        // 设置模拟的缓存信息
        // 在实际实现中，这里应该从缓存系统获取真实数据
        cacheStatus.setCacheSize("0 MB");
        cacheStatus.setCacheEntries(0);
        cacheStatus.setHitRate("0%");
        cacheStatus.setLastRefresh(java.time.LocalDateTime.now().toString());
        
        return cacheStatus;
    }
}